
package simuri.coherence;

import java.util.HashMap;
import java.util.Set;
import java.util.TreeSet;

/**
 *
 * @author Anwender
 */
public class SparseCoherenceMatrix implements CoherenceMatrix{  
    
    HashMap<String, HashMap<String, Double>> matrix;

    public SparseCoherenceMatrix() {
        matrix = new HashMap<String, HashMap<String, Double>>();
    }

    /** Returns the indexes of all rows of the matrix
     * 
     * @return Rows
     */
    public Set getRows()
    {
        return matrix.keySet();
    }
    
    /** Returns the indexes of all columns of the matrix
     * 
     * @return Rows
     */
    public Set getColumns()
    {
        Set result = new TreeSet();
        for(String s: matrix.keySet())
        {
            result.addAll(matrix.get(s).keySet());
        }
        return result;
    }
    /** Stores the non-zero entries of the matrix. 
     * 
     * @param uri1 Row index
     * @param uri2 Column index
     * @param coherence Coherence value
     */
    @Override
    public void setCoherence(String uri1, String uri2, double coherence) {
        if (coherence != 0) {
            if (!matrix.containsKey(uri1)) {
                matrix.put(uri1, new HashMap<String, Double>());
            }
            matrix.get(uri1).put(uri2, coherence);
        }
        else
        {
            if(matrix.containsKey(uri1))
            {
                if(matrix.get(uri1).containsKey(uri2))
                {
                    matrix.get(uri1).remove(uri2);
                }
            }
        }
    }

    /** Returns the value of the coherence
     * 
     * @param uri1 Row index
     * @param uri2 Column index
     * @return Coherence value
     */
    @Override
    public double getCoherence(String uri1, String uri2) {
        if (!matrix.containsKey(uri1)) {
            return 0;
        } else {
            if (!matrix.get(uri1).containsKey(uri2)) {
                return 0;
            } else {
                return matrix.get(uri1).get(uri2);
            }
        }
    }

    @Override
    public void normRows() {
        double sum;
        for (String uri1 : matrix.keySet()) {
            //compute sum of coherences
            sum = 0;
            for (String uri2 : matrix.get(uri1).keySet()) {
                if(!uri1.equals(uri2))
                sum = sum + matrix.get(uri1).get(uri2);
            }

            //norm by using the sum
            // avoid dividing by 0
            if (sum > 0) {
                for (String uri2 : matrix.get(uri1).keySet()) {
                    if(uri1.equals(uri2)) matrix.get(uri1).put(uri2, 1.0);
                    else matrix.get(uri1).put(uri2, matrix.get(uri1).get(uri2) / sum);
                }
            }
        }
    }
    
    public String toString()
    {
        return matrix.toString();
    }
    
}
